AWS Step FunctionsステートマシンでDynamoDBテーブルからアイテムを取得してMapステートで処理する
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、AWS Step FunctionsステートマシンでDynamoDBテーブルからアイテムを取得してMapステートで処理してみました。
作るもの
指定のエリアにいるクルーに次に移動するべきエリアを通知するアプリです。
やってみた
対象のDynamoDBテーブル
下記のクルーの現在位置と従業員情報を管理するDynamoDBテーブルをクエリ対象とします。
- テーブル名:
crews
- PK:
crewId
(String) - GSI名:
areaId-index
- GSI-PK:
areaId
(String)
格納されているデータは以下となります。
ステートマシンの作成
Step Functions Workflow Studioでステートマシンを作成します。
Step Functionsのマネジメントコンソールでステートマシンの作成を開始します。
[次へ]をクリックします。
[action]をquery
で検索して[DynamoDB Query]をドラッグします。
[Query]の[設定]で、[APIパラメータ]で下記のJSONを指定します。
{ "TableName": "crews", "IndexName": "areaId-index", "ExpressionAttributeNames": { "#areaId": "areaId" }, "ExpressionAttributeValues": { ":areaId": { "S.$": "$.areaId" } }, "KeyConditionExpression": "#areaId = :areaId" }
[Query]の[出力]で、[ResultSelector]と[ResultPath]を指定します。
- ResultSelector
{ "Items.$": "$.Items" }
- ResultPath
$.crews
[フロー]から[Query]の下の位置へ[Map]をドラッグして追加します。
Map
の[設定]-[項目配列へのパス]で$.crews.Items
を指定します。
同じくMap
の[入力]-[配列項目を変換]で以下のJSONを指定します。
{ "phoneNumber.$": "$$.Map.Item.Value.phoneNumber.S", "message.$": "$.message", "senderId.$": "$.senderId" }
[アクション]から[Amazon SNS]のPublish
をMap
の中にドラッグして追加します。
SNS Publish
の[設定]で[Integration type]をAWS SDK
に変更し、[APIパラメータ]に以下のJSONを指定します。
{ "PhoneNumber.$": "$.phoneNumber", "Message.$": "$.message", "MessageAttributes": { "AWS.SNS.SMS.SenderID": { "DataType": "String", "StringValue.$": "$.senderId" } } }
その後、[次へ]をクリックします。
生成されたコードを確認したら[次へ]をクリックします。
今回生成されたコード(ステートマシン定義)は下記のようになります。
{ "Comment": "A description of my state machine", "StartAt": "Query", "States": { "Query": { "Type": "Task", "Parameters": { "TableName": "crews", "IndexName": "areaId-index", "ExpressionAttributeNames": { "#areaId": "areaId" }, "ExpressionAttributeValues": { ":areaId": { "S.$": "$.areaId" } }, "KeyConditionExpression": "#areaId = :areaId" }, "Resource": "arn:aws:states:::aws-sdk:dynamodb:query", "ResultSelector": { "Items.$": "$.Items" }, "ResultPath": "$.crews", "Next": "Map" }, "Map": { "Type": "Map", "End": true, "Iterator": { "StartAt": "SNS Publish", "States": { "SNS Publish": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:sns:publish", "Parameters": { "PhoneNumber.$": "$.phoneNumber", "Message.$": "$.message", "MessageAttributes": { "AWS.SNS.SMS.SenderID": { "DataType": "String", "StringValue.$": "$.senderId" } } }, "End": true } } }, "ItemsPath": "$.crews.Items", "Parameters": { "phoneNumber.$": "$$.Map.Item.Value.phoneNumber.S", "message.$": "$.message", "senderId.$": "$.senderId" } } } }
[ステートマシンの作成]をクリックして作成を完了します。
ステートマシンを作成できました。不足しているDynamoDBへのアクセス権限を付与するために[IAMでロールを編集]をクリックします。
今回はAWS管理ポリシーのAmazonDynamoDBReadOnlyAccessをアタッチしました。(ポリシーは必要に応じて用意してください)
動作
Step Functionsのコンソールに戻り、入力で下記のようなJSONを指定して、ステートマシンを実行します。a001
のエリアにいるクルーにTaito-Ku
に移動するように通知する入力です。
{ "areaId": "a001", "message": "Please move to Taito-Ku.", "senderId": "AllocateApp" }
実行が成功しました。
それぞれのクルーの電話番号の端末でもSMSのメッセージが受信できています。
参考
- Step Functions の入出力処理 - AWS Step Functions
- AWS Step FunctionsステートマシンからDynamoDBテーブルをQueryする | DevelopersIO
- [AWS Step Functions] Mapステートを使用して複数の宛先にSMSメッセージを送信する | DevelopersIO
以上